#include "binarize.h"
#include <math.h>

Binarize::Binarize(Image* input)
{
	m_image = input;
}

void Binarize::binarizeKmeans()
{
    int i, j;
    int m1 = 0, m2 = 255,
                     last_m1, last_m2,
                     dif_m1, dif_m2;

    do {
        last_m1 = m1;
        last_m2 = m2;

        KmeansClutter(&m1, &m2);
    } while (last_m1 != m1);

    /// binarize image
    for (i = 0; i < m_image->h; i++) {
        for (j = 0; j < m_image->w; j++) {
			dif_m1 = abs(m1 - m_image->pixels[i][j]);
            dif_m2 = abs(m2 - m_image->pixels[i][j]);
            if (dif_m1 < dif_m2) { /// belong to 1 set
                m_image->pixels[i][j] = 1;
            } else { /// belong to set 2
                m_image->pixels[i][j] = 0;
            }
        }
    }
}

void Binarize::KmeansClutter(int *m1, int *m2)
{
    int i, j,
    new_m1 = 0, new_m2 = 0,
                         dif_m1, dif_m2,
                         num_m1 = 0, num_m2 = 0;

    /// assignment step
	for (i = 0; i < m_image->h; i++) {
		for (j = 0; j < m_image->w; j++) {
            dif_m1 = abs(*m1 - m_image->pixels[i][j]);
            dif_m2 = abs(*m2 - m_image->pixels[i][j]);

            if (dif_m1 < dif_m2) { /// belong to 1 set
                new_m1 += m_image->pixels[i][j];
                num_m1 ++;
            } else { /// belong to set 2
                new_m2 += m_image->pixels[i][j];
                num_m2 ++;
            }
        }
    }

    /// update step
    *m1 = new_m1 / num_m1;
    *m2 = new_m2 / num_m2;
}

void Binarize::runBinarize()
{
	binarizeKmeans();
}

